package com.projectsexception.festivales.db;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.projectsexception.festivales.favorites.model.Favorite;
import com.projectsexception.festivales.news.model.Feed;
import com.projectsexception.festivales.setup.ProjectResources;
import com.projectsexception.festivales.util.CustomLog;
import com.projectsexception.festivales.util.Serializator;

public final class DBAdapter {
    
    private static final String FEED_CACHE_TYPE = "feedCache";

    private static DBAdapter dbAdapter;
    
    private DBHelper dBHelper;
    
    public static DBAdapter getInstance(Context context) {
        if (dbAdapter == null) {
            dbAdapter = new DBAdapter(context);
        }
        return dbAdapter;
    }
        
    private DBAdapter(Context context) {
        dBHelper = new DBHelper(context);
    }
    
    public void saveFeedCache(Feed feed) {
        saveCache(FEED_CACHE_TYPE, Integer.toString(feed.getFeedInfoId()), feed);
    }
    
    public Feed loadFeedCache(Integer actualFeed) {
        return (Feed) getCache(FEED_CACHE_TYPE, actualFeed.toString()).getObject();
    }
    
    public void deleteAllFeedCache() {
        deleteCache(FEED_CACHE_TYPE);
    }
    
    public List<Favorite> getFavorites() {
        List<Favorite> result = new ArrayList<Favorite>();
        CustomLog.debug("DBAdapter", "getFavorites");
        ProjectResources resources = ProjectResources.getInstance();
        SQLiteDatabase db = dBHelper.getWritableDatabase();        
        Cursor c = db.query(DBHelper.FAVORITES_TABLE, 
                new String[] {DBHelper.COL_ID, DBHelper.COL_SHOW_ID}, 
                null, null, null, null, null);  
        if (c != null) {
            Favorite fav;
            while (c.moveToNext()) {
                fav = new Favorite();
                fav.setId(c.getInt(0));
                fav.setShowInfo(resources.getShow(c.getString(1)));
                result.add(fav);
            }
        }
        closeResources(c);
        return result;
    }
    
    public void saveFavorite(Favorite favorite) {
        CustomLog.debug("DBAdapter", "saveFavorite");
        SQLiteDatabase db = dBHelper.getWritableDatabase();
        ContentValues initialValues = new ContentValues();
        initialValues.put(DBHelper.COL_SHOW_ID, favorite.getShowInfo().getId());
        if (favorite.getId() == 0) {
            db.insert(DBHelper.FAVORITES_TABLE, null, initialValues);
        } else {
            db.update(DBHelper.FAVORITES_TABLE, initialValues, 
                    DBHelper.COL_ID + " = ?", new String[] {Integer.toString(favorite.getId())});
        }
    }
    
    public void deleteFavorite(Favorite favorite) {
        CustomLog.debug("DBAdapter", "deleteFavorite");
        SQLiteDatabase db = dBHelper.getWritableDatabase();
        db.delete(DBHelper.FAVORITES_TABLE, 
                DBHelper.COL_ID + " = ?", new String[] {Integer.toString(favorite.getId())});
    }
    
    private void saveCache(String type, String code, Object object) {
        SQLiteDatabase db = dBHelper.getWritableDatabase();
        if (object != null) {
            db.delete(DBHelper.CACHE_TABLE,
                    DBHelper.COL_TYPE + " = ? AND " + DBHelper.COL_CODE + " = ?", 
                    new String[] { type, code });
            if (Serializable.class.isAssignableFrom(object.getClass())) {
                byte[] array = Serializator.exportObject((Serializable) object);
                if (array != null) {
                    ContentValues values = new ContentValues();
                    values.put(DBHelper.COL_TYPE, type);
                    values.put(DBHelper.COL_CODE, code);
                    values.put(DBHelper.COL_UPDATED, new Date().getTime());
                    values.put(DBHelper.COL_DATA, array);
                    db.insert(DBHelper.CACHE_TABLE, null, values);
                }
            }
            
        }
    }
    
    private CacheObject getCache(String type, String code) {
        SQLiteDatabase db = dBHelper.getWritableDatabase();
        Cursor c = db.query(DBHelper.CACHE_TABLE, 
                new String[] { DBHelper.COL_UPDATED, DBHelper.COL_DATA }, 
                DBHelper.COL_TYPE + " = ? AND " + DBHelper.COL_CODE + " = ?", 
                new String[] { type, code }, 
                null, null, null);
        Object o = null;
        long updated = 0;
        if (c != null && c.moveToNext()) {
            updated = c.getLong(0);
            byte[] array = c.getBlob(1);
            o = Serializator.importObject(array);
        }
        closeResources(c);
        return new CacheObject(o, updated);
    }

    private void deleteCache(String type) {
        SQLiteDatabase db = dBHelper.getWritableDatabase();
        db.delete(DBHelper.CACHE_TABLE,
                DBHelper.COL_TYPE + " = ? ", 
                new String[] { type });
    }
    
    private static void closeResources(Cursor cursor) {
        if (cursor != null) {
            cursor.close();
        }
    }

}
